package com.pms.api;

import com.alibaba.fastjson.JSON;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.pms.controller.BaseController;
import com.pms.entity.AlipayNotifyData;
import com.pms.entity.PayConfigAli;
import com.pms.entity.PayTradeRecord;
import com.pms.exception.RRException;
import com.pms.service.IAliPayService;
import com.pms.service.IPayAccountBusService;
import com.pms.service.IPayTradeRecordService;
import com.pms.service.IThirdPayService;
import com.pms.util.alipay.RequestUtils;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;

/**
 * Created by ljb on 2017/8/21.
 * 用于第三方支付回调
 */
@RestController
@Api(value = "支付回调接口(这个不用管)", tags = {"支付回调接口(这个不用管)"})
@RequestMapping("/api/pay/thirdNotify")
public class ApiPayThirdNotifyController extends BaseController{

    @Autowired
    private IPayTradeRecordService iPayTradeRecordService;
    @Autowired
    private IThirdPayService iThirdPayService;
    @Autowired
    private IAliPayService iAliPayService;
    @Autowired
    private IPayAccountBusService iPayAccountBusService;

    /**
     * 支付宝回调方法
     * @param request
     * @param response
     */
    @RequestMapping(value = "/alipay")
    public void notify(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> underScoreKeyMap = RequestUtils.getStringParams(request);
        Map<String, String> camelCaseKeyMap = RequestUtils.convertKeyToCamelCase(underScoreKeyMap);
        logger.info("支付宝回调: 进入支付宝回调！");

        //获取回调参数
        String jsonString = JSON.toJSONString(camelCaseKeyMap);
        AlipayNotifyData notice = JSON.parseObject(jsonString, AlipayNotifyData.class);
        String trxNo = notice.getOutTradeNo();
        String thirdNo = notice.getTradeNo();
        //查看支付宝配置公钥
        PayTradeRecord payTradeRecord = iPayTradeRecordService.selectOne(
                new EntityWrapper<PayTradeRecord>().eq("trade_no", trxNo));
        if (payTradeRecord == null) {
            throw new RRException("支付记录不存在！");
        }

        PayConfigAli payConfigAli = iPayAccountBusService.getAliConfigByNo(payTradeRecord.getAccountNo());
        //验签
        boolean verifyResult = iAliPayService.verifyByAli(underScoreKeyMap,payConfigAli.getAliPublicKey());

        PrintWriter printWriter = null;
        try {
            printWriter = response.getWriter();
            if (verifyResult) {
                logger.info("支付宝回调: 验证签名成功！");
                printWriter.print("success");

                if (notice.getTradeStatus().equals("TRADE_SUCCESS")) {
                    //支付成功
                    logger.info("支付宝回调:支付成功,notice.getOutTradeNo()=" + notice.getOutTradeNo());

                    //判断是否是重复的回调请求?不重复修改支付记录
                    if(payTradeRecord.getPayState() != null){
                        throw new RRException("已经处理过的回调请求,支付状态已经是SUCCESS! ");
                    }
                    payTradeRecord.setPayState("SUCCESS");
                    payTradeRecord.setPaySuccessTime(new Date());
                    payTradeRecord.setThirdNo(thirdNo);
                    iPayTradeRecordService.updateById(payTradeRecord);

                    // todo 查看订单来自哪个系统，修改该系统订单状态
//                    iThirdPayService.updateStateByTrxNo(trxNo,thirdNo);
                }

                if(notice.getTradeStatus().equals("REFUND_SUCCESS")){
                    //支付宝退款成功回调
                    //暂时保留  发消息通知用户等操作....
                }

            }else{
                logger.info("支付宝回调: 验证签名失败！");
            }

        }catch (Exception e){
            e.printStackTrace();
            logger.error("alipay notify error :", e);
            printWriter.close();
        }finally {
            if (printWriter != null) {
                printWriter.close();
            }
        }

    }
}
